Vuelidate 2 is a popular form validation library made for the Vue 3 apps.
In this article, we’ll look at how to add form validation to our Vue 3 app with Vuelidate 2.
Validating Forms Before Submitting
We can validate forms right before we submit them.
To do this, we write:
<template>
<form @submit.prevent="submitForm">
<div>
<input v-model="v$.name.$model" />
<template v-if="v$.name.$dirty">
<div v-for="error of v$.name.$silentErrors" :key="error.$message">
{{ error.$message }}
</div>
</template>
</div>
<input type="submit" />
</form>
</template>
<script>
import useVuelidate from "@vuelidate/core";
import { required } from "@vuelidate/validators";
export default {
name: "App",
setup() {
return { v$: useVuelidate() };
},
data() {
return {
name: "",
};
},
validations() {
return {
name: { required, $lazy: true },
};
},
methods: {
submitForm() {
this.v$.$touch();
if (this.v$.$error) return;
alert("success");
},
},
};
</script>
We have a form that we wrapped around the input.
Then we add the submitForm
method, which calls v$.$touch
to trigger validation for each field in the form.
If there’re any errors, then this.$v.$error
will be truthy and we stop running the function.
Otherwise, the form is valid, we proceed and the alert is shown.
Validation can also be done asynchronously.
For instance, we can write:
<template>
<form [@submit](https://medium.com/r/?url=http%3A%2F%2Ftwitter.com%2Fsubmit "Twitter profile for @submit").prevent="submitForm">
<div>
<input v-model="v$.name.$model" />
<template v-if="v$.name.$dirty">
<div v-for="error of v$.name.$silentErrors" :key="error.$message">
{{ error.$message }}
</div>
</template>
</div>
<input type="submit" />
</form>
</template>
<script>
import useVuelidate from "@vuelidate/core";
import { required } from "@vuelidate/validators";
export default {
name: "App",
setup() {
return { v$: useVuelidate() };
},
data() {
return {
name: "",
};
},
validations() {
return {
name: { required, $lazy: true },
};
},
methods: {
async submitForm() {
const isFormValid = await this.v$.$validate();
if (!isFormValid) return;
alert("success");
},
},
};
</script>
We call this.v$.$validate()
to validate the form.
It returns a promise that resolves to true
if all the form values are valid.
Otherwise, the returned promise resolves to false
.
Composition API
We can use Vuelidate 2 with Vue 3’s Composition API./
To do this, we write:
<template>
<div>
<input v-model="v$.name.$model" />
<template v-if="v$.name.$dirty">
<div v-for="error of v$.name.$silentErrors" :key="error.$message">
{{ error.$message }}
</div>
</template>
</div>
</template>
<script>
import useVuelidate from "@vuelidate/core";
import { required, minLength } from "@vuelidate/validators";
import { computed, ref } from "vue";
export default {
name: "App",
setup() {
const name = ref("");
const requiredNameLength = ref(2);
const rules = computed(() => ({
name: {
required,
minLength: minLength(requiredNameLength.value),
},
}));
const v$ = useVuelidate(rules, { name });
return { name, requiredNameLength, v$ };
},
};
</script>
We define the name
reactive property with the ref
function.
requiredNameLength
is another reactive property that we use in the minLength
function.
minLength
validates that the inputted string is at least a given length.
We pass all the rules provided by Vuelidate into the object we return in the callback we pass into the computed
property.
Then we call useVuelidate
to return the object we use in the template.
Now we can display the errors and bind to the model the same way the previous example in the template.
Conclusion
We can validate our forms before submission and use Vuelidate with Vue 3’s Composition API.